package ntd.util.modular.other.controller;

import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.TypeUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.hutool.log.StaticLog;
import com.ToolOpt;
import com.modular.logs.bean.LogRecordsDo;
import com.modular.system.bigtext.ToolText;
import com.tool.ToolSpring;
import ntd.action.ActionManager;
import ntd.action.bo.ActionInBo;
import ntd.action.bo.ActionInfo;
import ntd.action.bo.ActionOutBo;
import ntd.util.config.common.bo.ResponseBO;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/action")
public class ControllerAction {

    @RequestMapping(value = "{action}/{dataCode}", method = {RequestMethod.GET, RequestMethod.POST})
    public Object distribution(@RequestBody(required = false) String body,
                                   @RequestParam Map<String, Object> params,
                                   @PathVariable(value = "dataCode", required = false) String dataCode,
                                   @PathVariable("action") String action
    ) {
        ActionInfo actionInfo = CollectionUtil.findOne(ActionManager.list(), item -> item.getActionCode().equals(action));
        if (ObjectUtil.isNull(actionInfo)) {
            return ResponseBO.err("没有匹配的动作！");
        }

        ActionInBo actionInBo = new ActionInBo().setDataStr(body)
                .setData(new Dict(JSONUtil.parseObj(body)))
                .setParam(new Dict(params))
                .setDataCode(dataCode);

        // 日志记录
        LogRecordsDo logRecordsDo = new LogRecordsDo();
        logRecordsDo.setType(StrUtil.format("API:动作[{}]", action));
        logRecordsDo.setUri(ToolSpring.ip());
        logRecordsDo.setSource("API调用");
        logRecordsDo.setTextId(ToolText.push(JSONUtil.toJsonStr(actionInBo)));
        ToolOpt.OPT_LOG.pushLog(logRecordsDo);

        // 执行动作
        ActionOutBo res = actionInfo.getAction().execute(actionInBo);

        Object data = res.getData();

        if (data instanceof byte[]) {
            return Convert.convert(byte[].class, data);
        }

        if (ObjectUtil.isBasicType(data) || data instanceof String) {
            return new ResponseBO<>(data);
        }

        return new ResponseBO<>(JSONUtil.parse(JSONUtil.toJsonStr(res.getData())));
    }

    @RequestMapping(value = "img/{action}/{dataCode}", produces = MediaType.IMAGE_JPEG_VALUE, method = RequestMethod.GET)
    public Object distributionGet(@RequestParam Map<String, Object> params, @PathVariable("dataCode") String dataCode, @PathVariable("action") String action
    ) {
        return distribution("{}", params, dataCode, action);
    }

    @GetMapping
    public ResponseBO<JSONObject> list(@RequestParam Map<String, String> params) {
        String platformType = params.get("platformType");

        List<JSONObject> jsonObjects = CollStreamUtil.toList(CollectionUtil.filter(ActionManager.list(), actionInfo -> isPlatformType(platformType, actionInfo)),
                actionInfo -> generatorActionObj(actionInfo));

        return new ResponseBO<>(jsonObjects);
    }

    private static JSONObject generatorActionObj(ActionInfo actionInfo) {
        JSONObject obj = JSONUtil.createObj();
        obj.set("actionCode", actionInfo.getActionCode());
        obj.set("name", actionInfo.getName());
        return obj;
    }

    private static boolean isPlatformType(String platformType, ActionInfo actionInfo) {
        if (StrUtil.isNotBlank(platformType)) {
            return platformType.equals(actionInfo.getPlatform());
        }
        return true;
    }

    public static void main(String[] args) {
        List<ActionInfo> list = ActionManager.list();
        StaticLog.info(JSONUtil.toJsonStr(list));
    }

}
